import { ITypeEntity } from '@/types/modules/superType/types';
import { FileTypeManager, FileTypeConfig } from '../config/file-types.config';
import { pageStore } from '@/pages/editor/store/page';

/**
 * 文件创建选项
 */
export interface FileCreationOptions {
  /** 文件名 */
  name: string;
  /** 文件描述 */
  desc?: string;
  /** 文件夹路径 */
  folder?: string;
  /** 项目ID */
  projectId?: string;
  /** 自定义内容 */
  content?: string;
  /** 自定义数据 */
  data?: any;
}

/**
 * 文件类型工厂
 */
export class FileTypeFactory {
  private fileTypeManager: FileTypeManager;

  constructor() {
    this.fileTypeManager = FileTypeManager.getInstance();
  }

  /**
   * 创建文件实体
   */
  createFileEntity(type: ITypeEntity['type'], options: FileCreationOptions): ITypeEntity {
    const config = this.fileTypeManager.getConfig(type);
    if (!config) {
      throw new Error(`不支持的文件类型: ${type}`);
    }

    // 检查路径权限
    const targetPath = this.getTargetPath(config, options.folder);
    if (!this.fileTypeManager.isPathAllowed(type, targetPath)) {
      throw new Error(`不允许在路径 ${targetPath} 创建 ${config.displayName}`);
    }

    // 获取内容
    const content = options.content || this.fileTypeManager.getDefaultTemplate(type);

    // 验证内容
    const validation = this.fileTypeManager.validateContent(type, content);
    if (!validation.valid) {
      throw new Error(`文件内容验证失败: ${validation.error}`);
    }

    // 执行创建前钩子
    let processedOptions = options;
    if (config.entityHooks?.beforeCreate) {
      processedOptions = config.entityHooks.beforeCreate(options, config);
    }

    // 生成默认值
    let defaults: Partial<ITypeEntity> = {};
    if (config.entityHooks?.generateDefaults) {
      defaults = config.entityHooks.generateDefaults(processedOptions, config);
    }

    // 推断语言
    let language = config.language;
    if (config.entityHooks?.inferLanguage) {
      language = config.entityHooks.inferLanguage(content, processedOptions, config);
    } else if (type === 'code') {
      language = this.inferLanguageFromContent(content);
    }

    // 解析数据
    let data = processedOptions.data;
    if (!data) {
      if (config.entityHooks?.parseData) {
        data = config.entityHooks.parseData(content, processedOptions, config);
      } else {
        data = this.parseContentToData(content, config);
      }
    }

    // 创建实体
    const entity: ITypeEntity = {
      type,
      name: processedOptions.name,
      desc: processedOptions.desc || processedOptions.name,
      folder: processedOptions.folder || config.defaultPath,
      projectId: processedOptions.projectId || pageStore.currentProjectId,
      source: content,
      language: language || config.language,
      data: data || defaults.data,
      // 合并默认值
      ...defaults,
    };

    // 执行创建后钩子
    let finalEntity = entity;
    if (config.entityHooks?.afterCreate) {
      finalEntity = config.entityHooks.afterCreate(entity, processedOptions, config);
    }

    return finalEntity;
  }

  /**
   * 批量创建文件实体
   */
  createMultipleFileEntities(
    requests: Array<{ type: ITypeEntity['type']; options: FileCreationOptions }>,
  ): ITypeEntity[] {
    return requests.map(({ type, options }) => this.createFileEntity(type, options));
  }

  /**
   * 获取文件类型的创建向导配置
   */
  getCreationWizardConfig(type: ITypeEntity['type']): {
    config: FileTypeConfig;
    fields: Array<{
      name: string;
      label: string;
      type: 'input' | 'textarea' | 'select' | 'switch';
      required?: boolean;
      options?: Array<{ label: string; value: any }>;
      placeholder?: string;
      defaultValue?: any;
    }>;
  } {
    const config = this.fileTypeManager.getConfig(type);
    if (!config) {
      throw new Error(`不支持的文件类型: ${type}`);
    }

    // 基础字段
    const fields = [
      {
        name: 'name',
        label: '文件名',
        type: 'input' as const,
        required: true,
        placeholder: `请输入${config.displayName}名称`,
      },
      {
        name: 'desc',
        label: '描述',
        type: 'input' as const,
        placeholder: `请输入${config.displayName}描述`,
      },
    ];

    // 文件夹选择
    if (config.allowedPaths && config.allowedPaths.length > 1) {
      fields.push({
        name: 'folder',
        label: '存储位置',
        type: 'select' as const,
        required: true,
        options: config.allowedPaths.map((path) => ({
          label: path,
          value: path,
        })),
        defaultValue: config.defaultPath,
      });
    }

    // 特定类型的额外字段
    switch (type) {
      case 'code':
        fields.push({
          name: 'language',
          label: '语言类型',
          type: 'select' as const,
          options: [
            { label: 'Markdown', value: 'markdown' },
            { label: 'JavaScript', value: 'javascript' },
            { label: 'TypeScript', value: 'typescript' },
            { label: 'JSON', value: 'json' },
            { label: 'CSS', value: 'css' },
          ],
          defaultValue: 'markdown',
        });
        break;

      case 'diagram':
        fields.push({
          name: 'diagramType',
          label: '图表类型',
          type: 'select' as const,
          options: [
            { label: 'Mermaid', value: 'mermaid' },
            { label: 'PlantUML', value: 'plantuml' },
            { label: 'Graphviz', value: 'graphviz' },
          ],
          defaultValue: 'mermaid',
        });
        break;

      case 'flow':
        fields.push({
          name: 'flowType',
          label: '流程图类型',
          type: 'select' as const,
          options: [
            { label: '业务流程', value: 'business' },
            { label: '系统流程', value: 'system' },
            { label: '数据流程', value: 'data' },
          ],
          defaultValue: 'business',
        });
        break;
    }

    return { config, fields };
  }

  /**
   * 获取目标路径
   */
  private getTargetPath(config: FileTypeConfig, folder?: string): string {
    return folder || config.defaultPath;
  }

  /**
   * 从内容推断语言类型
   */
  private inferLanguageFromContent(content: string): string {
    // 简单的语言推断逻辑
    if (content.startsWith('#') || content.includes('##')) {
      return 'markdown';
    }
    if (content.startsWith('{') || content.startsWith('[')) {
      return 'json';
    }
    if (content.includes('function') || content.includes('=>')) {
      return 'javascript';
    }
    if (content.includes('interface') || content.includes('type ')) {
      return 'typescript';
    }
    return 'text';
  }

  /**
   * 解析内容为数据对象
   */
  private parseContentToData(content: string, config: FileTypeConfig): any {
    if (!content) return null;

    try {
      // 对于 JSON 类型的文件，尝试解析
      if (config.language === 'json' || content.trim().startsWith('{')) {
        return JSON.parse(content);
      }
    } catch {
      // 解析失败，返回原始内容
    }

    return null;
  }

  /**
   * 获取文件类型的图标
   */
  getFileTypeIcon(
  type: ITypeEntity['type'],
): { color: string; svg: string } | string {
    const config = this.fileTypeManager.getConfig(type);
    return config?.icon || 'FileOutlined';
  }

  /**
   * 获取文件类型的显示名称
   */
  getFileTypeDisplayName(type: ITypeEntity['type']): string {
    const config = this.fileTypeManager.getConfig(type);
    return config?.displayName || type;
  }

  /**
   * 检查文件类型是否支持某个功能
   */
  supportsFeature(type: ITypeEntity['type'], feature: 'versionControl' | 'search'): boolean {
    const config = this.fileTypeManager.getConfig(type);
    if (!config) return false;

    switch (feature) {
      case 'versionControl':
        return config.versionControl ?? true;
      case 'search':
        return config.searchable ?? true;
      default:
        return false;
    }
  }

  /**
   * 获取文件类型的编辑器组件
   */
  getEditorComponent(type: ITypeEntity['type']): string | undefined {
    const config = this.fileTypeManager.getConfig(type);
    return config?.editorComponent;
  }

  /**
   * 验证文件名是否合法
   */
  validateFileName(name: string, type: ITypeEntity['type']): { valid: boolean; error?: string } {
    if (!name || name.trim().length === 0) {
      return { valid: false, error: '文件名不能为空' };
    }

    // 检查非法字符
    const invalidChars = /[<>:"/\\|?*]/;
    if (invalidChars.test(name)) {
      return { valid: false, error: '文件名包含非法字符' };
    }

    // 检查长度
    if (name.length > 100) {
      return { valid: false, error: '文件名过长（最多100个字符）' };
    }

    // 检查保留名称
    const reservedNames = ['con', 'prn', 'aux', 'nul', 'com1', 'com2', 'lpt1', 'lpt2'];
    if (reservedNames.includes(name.toLowerCase())) {
      return { valid: false, error: '文件名为系统保留名称' };
    }

    return { valid: true };
  }
}

export default new FileTypeFactory();
